// See Graphics.h for info

#include "Graphics.h"

// Globals

bool Graphics::init_graphics()
{
	if ( SDL_Init( SDL_INIT_EVERYTHING ) == -1 ) return false;
	if ( TTF_Init() == -1 ) return false;
	return true;

}

void Graphics::cleanup_graphics()
{
	TTF_Quit();
	SDL_Quit();
}

// Screen

Graphics::Screen::Screen( int w, int h, std::string title )
{
	this->screen = SDL_SetVideoMode( w, h, 32, SDL_SWSURFACE );
	SDL_WM_SetCaption( title.c_str(), NULL );

	if ( this->screen == NULL ) throw "Unable to load screen surface.";

	this->clear_colour = SDL_MapRGB( this->screen->format, 0, 0, 0 );
}

Graphics::Screen::~Screen()
{
}

void Graphics::Screen::begin()
{
	SDL_FillRect( this->screen, &this->screen->clip_rect, this->clear_colour );
}

void Graphics::Screen::end()
{
	if ( SDL_Flip( this->screen ) == -1 ) throw "Unable to flip screen.";
}

void Graphics::Screen::draw( int x, int y, Texture* texture )
{
	SDL_Rect offset;
	offset.x = x;
	offset.y = y;
	offset.w = texture->width;
	offset.h = texture->height;

	SDL_BlitSurface( texture->image, NULL, this->screen, &offset );
}

void Graphics::Screen::draw_rect( int x, int y, int width, int height, Graphics::Colour* colour )
{
	SDL_Rect dest;
	dest.x = x;
	dest.y = y;
	dest.w = width;
	dest.h = height;

	SDL_FillRect( this->screen, &dest, SDL_MapRGB( this->screen->format, colour->r, colour->g, colour->b) );
}

void Graphics::Screen::draw_string( int x, int y, std::string message, Graphics::Font* font, Graphics::Colour* colour )
{
	SDL_Surface* message_surface = NULL;
	SDL_Color tColour = { colour->r, colour->g, colour->b };
	message_surface = TTF_RenderText_Solid( font->font, message.c_str(), tColour );

	if ( message_surface == NULL) return;

	SDL_Rect dest;
	dest.x = x;
	dest.y = y;
	dest.w = message_surface->w;
	dest.h = message_surface->h;

	SDL_BlitSurface( message_surface, NULL, this->screen, &dest );
	SDL_FreeSurface( message_surface );
}

// Texture

Graphics::Texture::Texture( std::string filepath )
{
	// Load image
	this->image = NULL;
	SDL_Surface* loaded_image = NULL;
	SDL_Surface* optimised_image = NULL;

	loaded_image = IMG_Load( filepath.c_str() );
	if ( loaded_image != NULL )
	{
		optimised_image = SDL_DisplayFormatAlpha( loaded_image );
	}
	SDL_FreeSurface( loaded_image );
	this->image = optimised_image;
	if (optimised_image == NULL) throw "Unable to load image.";
	else
	{
		this->height = this->image->h;
		this->width = this->image->w;
	}
}

Graphics::Texture::~Texture()
{
	SDL_FreeSurface( this->image );
}

// Colour

Graphics::Colour::Colour()
{
	this->r = 0;
	this->g = 0;
	this->b = 0;
}

Graphics::Colour* Graphics::Colour::fromRGB( int red, int green, int blue )
{
	Graphics::Colour* colour = new Colour();
 	colour->r = red;
	colour->g = green;
	colour->b = blue;
	
	return colour;
}

// Font

Graphics::Font::Font()
{
	font = NULL;
}

Graphics::Font::Font( std::string filename, int size )
{
	font = NULL;

	font = TTF_OpenFont( filename.c_str(), size );
	if ( font == NULL ) throw "Unable to open font.";
}

Graphics::Font::~Font()
{
	TTF_CloseFont( font );
}

// Rect

Graphics::Rect::Rect()
{
	rect.x = 0;
	rect.y = 0;
	rect.w = 0;
	rect.h = 0;
}

Graphics::Rect::Rect( int x, int y, int w, int h )
{
	rect.x = x;
	rect.y = y;
	rect.w = w;
	rect.h = h;
}

Graphics::Rect::~Rect()
{
}

bool Graphics::Rect::intersects( Graphics::Rect* otherRect )
{
	throw "Not yet implemented.";
	return false;
}